package com.lgj.rocketmq.code;

import com.lgj.exception.BusinessException;
import com.lgj.rocketmq.annotation.RocketMqConsumer;
import com.lgj.rocketmq.annotation.RocketMqMessageListener;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
 * @author: guangjie.liao
 * @since: 2023/9/19 21:38
 * @description: 获取注解配置信息转换成 {@linkcom.lgj.rocketmq.code.Consumer}
 */
@Slf4j
public class ConsumerInitFactory implements ApplicationContextAware, InitializingBean {

    /**
     * 初始化DefaultMQPushConsumer 所需的配置信息
     * key topic
     * value Consumer
     */
    private static final Map<String, Consumer> consumerMap = new HashMap<>();

    /**
     * 处理消息方法
     */
    private static final Map<String,Method> handeMessageMethodMap = new HashMap<>();

    /**
     * 处理下消息类
     */
    private static final Map<String,Object> handeMessageBeanMap = new HashMap<>();

    public Map<String, Consumer> getConsumers(){
        return consumerMap;
    }

    public Map<String,Method> getHandeMessageMethods(){
        return handeMessageMethodMap;
    }


    public Map<String,Object> handeMessageBeanMap(){
        return handeMessageBeanMap;
    }
    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }


    @Override
    public void afterPropertiesSet() throws Exception {
        Map<String, Object> consumerBeanMap = applicationContext.getBeansWithAnnotation(RocketMqConsumer.class);
        if (consumerBeanMap.isEmpty()){
            return;
        }
        for (String beanName : consumerBeanMap.keySet()){
            Object consumerBean = consumerBeanMap.get(beanName);
            RocketMqConsumer rocketMqConsumer =  AopProxyUtils.ultimateTargetClass(consumerBean).getAnnotation(RocketMqConsumer.class);
            Consumer consumer = Consumer.convert(rocketMqConsumer);

            Method[] declaredMethods = AopProxyUtils.ultimateTargetClass(consumerBean).getDeclaredMethods();
            for (Method method : declaredMethods){
                if (method.isAnnotationPresent(RocketMqMessageListener.class)) {
                    RocketMqMessageListener listener = method.getAnnotation(RocketMqMessageListener.class);
                    String topic = listener.topic();
                    if (StringUtil.isNullOrEmpty(topic)){
                        throw new BusinessException("类 "+beanName.getClass().getName()
                                +",方法 "+method.getName()+",注解 RocketMqMessageListener 缺少 topic");
                    }
                    consumer.setTopic(topic);
                    //消费者配置
                    consumerMap.put(topic,consumer);
                    //执行处理消息的方法
                    handeMessageMethodMap.put(topic,method);
                    //处理方法所在类
                    handeMessageBeanMap.put(topic,consumerBean);
                }
            }
        }
    }
}
